﻿using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using élénkPróbája.extentions;
using élénkPróbája.Test.dto;
using élénkPróbája.Test.extention;
using élénkPróbája.validators;

namespace élénkPróbája.Test
{
    [TestClass]
    public class ExceedValidatorTester
    {
        private TestValidator validator;
        private const int value = 1;
        public ExceedValidatorTester()
        {
            CultureScope.SetDefaultCulture();
            validator = new TestValidator(v => v.RuleFor(x => x.Id).GreaterThan(value));
        }
         
        [TestMethod]
        public void Should_fail_when_less_than_input()
        {
            var result = validator.Validate(new Company { Id = 0 });
            result.IsValid.ShouldBeFalse();
        }

        [TestMethod]
        public void Should_succeed_when_greater_than_input()
        {
            var result = validator.Validate(new Company { Id = 2 });
            result.IsValid.ShouldBeTrue();
        }

        [TestMethod]
        public void Should_fail_when_equal_to_input()
        {
            var result = validator.Validate(new Company { Id = value });
            result.IsValid.ShouldBeFalse();
        }

        [TestMethod]
        public void Should_set_default_error_when_validation_fails()
        {
            var result = validator.Validate(new Company { Id = 0 });
            result.Errors.Single().ErrorMessage.ShouldEqual("'' must be greater than '1'.");
        }

        [TestMethod]
        public void Validates_with_property()
        {
            validator = new TestValidator(v => v.RuleFor(x => x.Id).GreaterThan(5));
            var result = validator.Validate(new Company { Id = 1 });
            result.IsValid.ShouldBeFalse();
        }

        [TestMethod]
        public void Validates_with_nullable_property()
        { 
            validator = new TestValidator(v => v.RuleFor(x => x.Id).GreaterThan(0));

            var resultNull = validator.Validate(new Company());
            var resultLess = validator.Validate(new Company { Id = -1 });
            var resultEqual = validator.Validate(new Company { Id = 0 });
            var resultMore = validator.Validate(new Company { Id = 1 });

            resultNull.IsValid.ShouldBeFalse();
            resultLess.IsValid.ShouldBeFalse();
            resultEqual.IsValid.ShouldBeFalse();
            resultMore.IsValid.ShouldBeTrue();
        }

        [TestMethod]
        public void Comparison_Type()
        {
            var propertyValidator = validator.CreateDescriptor()
                .GetValidatorsForMember("Id").OfType<ExceedValidator>().Single();

            propertyValidator.Comparison.ShouldEqual(Comparison.GreaterThan);
        }

        [TestMethod]
        public void Validates_with_nullable_when_property_is_null()
        {
            validator = new TestValidator(v => v.RuleFor(x => x.Id).GreaterThan(5));
            var result = validator.Validate(new Company());
            result.IsValid.ShouldBeFalse();
        }

        [TestMethod]
        public void Validates_with_nullable_when_property_not_null()
        {
            validator = new TestValidator(v => v.RuleFor(x => x.Id).GreaterThan(5));
            var result = validator.Validate(new Company { Id = 1 });
            result.IsValid.ShouldBeFalse();
        }


        [TestMethod]
        public void Validates_with_nullable_when_property_is_null_cross_property()
        {
            validator = new TestValidator(v => v.RuleFor(x => x.Id).GreaterThan(4));
            var result = validator.Validate(new Company { Id = 5 });
            result.IsValid.ShouldBeTrue();
        }

        [TestMethod]
        public void Validates_with_nullable_when_property_not_null_cross_property()
        {
            validator = new TestValidator(v => v.RuleFor(x => x.Id).GreaterThan(5));
            var result = validator.Validate(new Company { Id = 5 });
            result.IsValid.ShouldBeFalse();
        }
    }
}
